package com.caowei.weicimpress.weicimpress;

import android.content.Context;
import android.support.annotation.NonNull;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by caoweiPc on 2014/7/19.
 */
public abstract class AbstractFileHandler implements FileHandler {
    private static final String TAG=AbstractFileHandler.class.getSimpleName();
    protected List<File> compressingFiles=new ArrayList<File>();

    @Override
    public List<File> getCompressingFiles() {
        return compressingFiles;
    }

    @NonNull
    public String getNameOfFormat() {
        return nameOfFormat;
    }

    public void setNameOfFormat(@NonNull String nameOfFormat) {
        this.nameOfFormat = nameOfFormat;
    }

    /*处理器名字 如zip 文件的为 zip
        * */
    @NonNull
    protected String nameOfFormat;

    public Map<Integer, String> getDeflate_method() {
        return deflate_method;
    }


    protected Map<Integer,String> deflate_method=new HashMap<Integer,String>();
    protected int sort=0;
    protected Context mContext;

    public AbstractFileHandler(Context context){
        this.mContext=context;
    }

    public int compare(FileHandler fileHandler){
        int result=0;
        result= this.sort-((AbstractFileHandler)fileHandler).sort;
        return result;
    }

    @Override
    public MyDataList list( FileInfoBean fileInfoBean) {
        //todo  前后 扩展
        MyDataList myDataList= this.listfiles( fileInfoBean);
        Collections.sort(myDataList.getFileInfoBeans(),new Comparator<FileInfoBean>() {
            @Override
            public int compare(FileInfoBean lhs, FileInfoBean rhs) {
                StringBuilder lsb=new StringBuilder(lhs.getParentPath());
                lsb.append(File.separator).append(lhs.getFileName());
                StringBuilder rsb=new StringBuilder(rhs.getParentPath());
                rsb.append(File.separator).append(rhs.getFileName());
                String lstr=lsb.toString().toLowerCase();
                String rstr=rsb.toString().toLowerCase();
                return lstr.compareTo(rstr);
            }
        });
        BigDecimal internal= Utils.getInternalAllSpace();
        BigDecimal external= Utils.getExternalAllSpace();
        myDataList.setAllSpace(BigDecimal.ZERO.add(internal).add(external));
        return myDataList;
    }

    @Override
    public File compress(File saveFlie,String passwd,int compressmethod_key,List<FileInfoBean> srces) {
        if(srces==null||srces.isEmpty()){
            return null;
        }
        synchronized (this){
            compressingFiles.add(saveFlie);
        }
        File returnF= this.subCompress(saveFlie,passwd,compressmethod_key,srces);
        synchronized (this){
            compressingFiles.remove(saveFlie);
        }
        if(returnF==null&&saveFlie.exists()){
            Utils.del(saveFlie.getAbsolutePath());
        }
        return returnF;
    }

    @Override
    public  MainPartFile compress(File saveName,
                            final String passwd,
                            int compressmethod_key,
                            List<FileInfoBean> beans,
                            int subsize,
                            String unit){
        if(beans==null||beans.isEmpty()){
            return null;
        }
        synchronized (this){
            if(!compressingFiles.contains(saveName)){
                compressingFiles.add(saveName);
            }
        }

        MainPartFile returnF= this.subCompress( saveName,passwd,compressmethod_key,beans,subsize,unit);
        synchronized (this){
            if(compressingFiles.contains(saveName)){
                compressingFiles.remove(saveName);
            }
        }
        if(returnF.mainFile==null&&saveName.exists()){
            Utils.del(saveName.getAbsolutePath());
        }
        return returnF;
    }


  /*  @Override
    public  File[] compress(File targetDir,
                            String saveName,
                         String passwd,
                         int compressmethod_key,
                         FileInfoBean src,
                         int subsize,
                         String unit){
        RandomAccessFile randomAccessFile=null;
        FileChannel fileInChannel=null;
        FileChannel fileOutChannel=null;
        try {
            File targetTemp=File.createTempFile(saveName,".temp",targetDir);
            subCompress(targetTemp,passwd,compressmethod_key,src);
            int index= Arrays.binarySearch(Utils.UNITS,unit.toUpperCase());
            double subsize_B=  (Math.pow(Utils.SIZEUNIT,index)*subsize);
            randomAccessFile=new RandomAccessFile(targetTemp,"r");
            fileInChannel=randomAccessFile.getChannel();
            ByteBuffer byteBuffer=ByteBuffer.allocate(1024*5);
            byte[] bytes=new byte[byteBuffer.capacity()];
            if(targetTemp.length()<=subsize_B){
                File targetFile=new File(targetDir,saveName);
                boolean result= targetTemp.renameTo(targetFile);
                if(!result){
                    Log.d(TAG,"compress "+ src.getFileName()+" fail");
                    throw new MyException("compress "+ src.getFileName()+" fail");
                }
                return new File[]{targetFile};
            }else{
                int count=0;
                List<File> list=new ArrayList<File>();
                String saveName1= Utils.dropDotSuffix(saveName);
                String suffix=saveName.substring(saveName.lastIndexOf("."));
                int count1=1;
                File targetFile=new File(targetDir,saveName1+count1+suffix);
                if(targetFile.exists()){
                    targetFile.delete();
                }
                RandomAccessFile randomAccessFile1=  new RandomAccessFile(targetFile,"rw");
                fileOutChannel=randomAccessFile1.getChannel();
                list.add(targetFile);
                while ((fileInChannel.read(byteBuffer))!=-1){
                    if(count>subsize_B){
                        fileOutChannel.close();
                        fileOutChannel=null;
                        randomAccessFile1.close();
                        randomAccessFile1=null;
                        targetFile=new File(targetDir,saveName1+"-"+(++count1)+suffix);
                        if(targetFile.exists()){
                            targetFile.delete();
                        }
                        randomAccessFile1=new RandomAccessFile(targetFile,"rw");
                        fileOutChannel=randomAccessFile1.getChannel();
                        list.add(targetFile);
                    }

                    int size=byteBuffer.position();
                    count+=size;
                    byteBuffer.rewind();
                    fileOutChannel.write(byteBuffer);
                    byteBuffer.clear();
                }
                if(fileOutChannel!=null){
                    fileOutChannel.close();
                }
                if(randomAccessFile1!=null){
                    randomAccessFile1.close();
                }
                return list.toArray(new File[list.size()]);
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG,"创建："+saveName+".temp  fail");
            throw new MyException("创建："+saveName+".temp  fail",e);
        }finally {
            if(fileInChannel!=null){
                try {
                    fileInChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(randomAccessFile!=null){
                try {
                    randomAccessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if(fileOutChannel!=null){
                try {
                    fileOutChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    } ;*/

    public abstract MainPartFile subCompress(
                           File file,
                          String passwd,
                          int compressmethod_key,
                          List<FileInfoBean> beans,
                          int subsize,
                          String unit);

     @Override
    public boolean  checkCompressNoFinished(File file){
        return compressingFiles.contains(file);
    }

    protected abstract File subCompress(File saveFlie,String passwd,
                                        int compressmethod_key,List<FileInfoBean> fileInfoBeans) ;
    protected abstract MyDataList  listfiles( FileInfoBean fileInfoBean) ;

    public abstract boolean isSurpportCryptogram();
}
